/** ***************************************************************************
 * CoffeeMemory.hpp
 * 2012 CoffeeParty Ltd.
 * Date Created: 2012-07-21                                  format YYYY-MM-DD
 * Revision Id: $Id$
 ******************************************************************************
 */

#ifndef _COFFEE_MEMORY_HPP_
#define _COFFEE_MEMORY_HPP_

#include "CoffeeCommons.hpp"
#include "CoffeeString.hpp"
#include "CoffeeIO.hpp"

CoffeeMemory::CoffeeMemory(c_voidp data, c_long length, c_const_string &filename, c_bool _on_clean)
: bufdata(data), memlength(length), mempos(0), cfilename(filename), on_clean(_on_clean)
{
}

CoffeeMemory::~CoffeeMemory()
{
}

c_string CoffeeMemory::filename() const
{
    return cfilename;
}

c_size_t CoffeeMemory::size() const
{
    return memlength;
}

c_size_t CoffeeMemory::read(c_voidp data, c_size_t length)
{
    c_size_t amount = length;
    if (mempos + amount > memlength)
        amount -= mempos + amount - memlength;

    if (amount <= 0)
        return 0;

    c_bytep ptr = (c_bytep)bufdata;
    memcpy(data, ptr + mempos, amount);
    mempos += amount;

    return amount;
}

c_size_t CoffeeMemory::write(c_voidp data, c_size_t length)
{
    c_size_t amount = length;
    if (mempos + amount > memlength)
        amount -= mempos + amount - memlength;

    if (amount <= 0)
        return 0;

    c_bytep ptr = (c_bytep)bufdata;
    memcpy(ptr + mempos, data, amount);
    mempos += amount;

    return amount;
}

c_size_t CoffeeMemory::pos() const
{
    return mempos;
}

c_bool CoffeeMemory::seek(c_size_t offset, c_bool relative)
{
    if (relative)
    {
        if (mempos + offset > memlength)
            return false;
        mempos += offset;
    }
    else
    {
        if (offset > memlength)
            return false;
        mempos = offset;
    }
    return true;
}

#endif /** _COFFEE_MEMORY_HPP_ */
